import React, { FC, useState, useEffect, useCallback, useMemo } from 'react';
import { Input, Space, Spin, InputNumber, Badge } from 'antd';
import { isEmpty } from 'lodash';

import CollapseQueryBar from '@components/CollapseQueryBar';
import { useForm } from '@components/Form';
import Table from '@components/Table';
import Button from '@components/Button';
import EditDrawerForm from '@components/EditDrawerForm';

import { COMMON_PAGINATION, COMMON_REQUIRE_RULE, COMPLETELY_FILL_STYLE } from '@utils/config';
import { useResetFormOnCloseModal, generateCommonDeleteModal } from '@utils/renderer';
import request from '@utils/request';
import { getFormValues } from '@utils/util';
import notification from '@utils/notification';

interface DictionaryItemsProps {
  /** 当前选择字典code */
  currentDictId: string;

  /** 当前选择字典描述 */
  currentOption?: string;
}

const DictionaryItems: FC<DictionaryItemsProps> = ({ currentDictId, currentOption }) => {
  const [loading, setLoading] = useState<boolean>(false);
  const [saveLoading, setSaveLoading] = useState<boolean>(false);

  const [tableData, setTableData] = useState<any[]>([]);
  const [pagination, setPagination] = useState<any>(COMMON_PAGINATION);
  const [selectedRowKeys, setSelectedRowKeys] = useState<any[]>([]);
  const [selectedRows, setSelectedRows] = useState<any[]>([]);

  const [operationType, setOperationType] = useState<string>('');
  const [openFlag, setOpenFlag] = useState<boolean>(false);

  const [queryForm] = useForm(); // 查询表单
  const [editForm] = useForm(); // 编辑表单

  useResetFormOnCloseModal({ form: editForm, openFlag });

  /** 查询表格数据 */
  const handleQueryData = useCallback((params: any) => {
    setLoading(true);

    request({
      url: '/develop/dictionary/item',
      method: 'GET',
      params: { ...COMMON_PAGINATION, ...params }
    })
      .then((res: any) => {
        if (res) {
          const { current, size, total, records = [] } = res;
          // 设置分页数据
          setPagination({ ...COMMON_PAGINATION, current, size: size, total });
          setTableData(records);
          // 查询重置勾选
          setSelectedRowKeys([]);
          setSelectedRows([]);
        }
      })
      .finally(() => {
        setLoading(false);
      });
  }, []);

  useEffect(() => {
    if (currentDictId) {
      handleQueryData({ dictId: currentDictId });
    } else {
      // 数据重置
      setTableData([]);
      setPagination({});
      setSelectedRowKeys([]);
      setSelectedRows([]);
    }
  }, [currentDictId, handleQueryData]);

  /** 表单查询 */
  const handleSearch = useCallback(
    (values: any) => {
      if (currentDictId) handleQueryData({ dictId: currentDictId, ...values });
    },
    [currentDictId, handleQueryData]
  );

  /** 分页切换重新查询表格数据 */
  const handleTableChange = useCallback(
    async ({ current, size }: any) => {
      const fields = await getFormValues(queryForm);
      handleQueryData({ dictId: currentDictId, ...fields, current, size });
    },
    [currentDictId, handleQueryData, queryForm]
  );

  /** 打开 新增|编辑 抽屉 */
  const handleOpenEditDrawer = useCallback(
    (type: string) => {
      // 设置操作类型
      setOperationType(type);

      if (type === 'update') {
        // 设置抽屉表单数据
        editForm.setFieldsValue(selectedRows[0] || {});
      }

      // 打开抽屉
      setOpenFlag(true);
    },
    [editForm, selectedRows]
  );

  /** 保存 */
  const handleSave = useCallback(async () => {
    // 表单未修改
    if (!editForm.isFieldsTouched()) {
      // 关闭抽屉
      setOpenFlag(false);
      return;
    }

    // 校验获取值
    const fields = await editForm.validateFields();

    // 校验通过
    if (fields) {
      setSaveLoading(true);
      request({
        url: '/develop/dictionary/item',
        method: operationType === 'update' ? 'PUT' : 'POST',
        data: { dictId: currentDictId, ...selectedRows[0], ...fields }
      })
        .then(async (res: any) => {
          if (res) {
            notification.success();
            // 关闭抽屉
            setOpenFlag(false);
            const params = await getFormValues(queryForm);
            const { current, size } = pagination;
            // 查询最新数据
            handleQueryData({ dictId: currentDictId, ...params, current, size });
          }
        })
        .finally(() => {
          setSaveLoading(false);
        });
    }
  }, [
    currentDictId,
    editForm,
    handleQueryData,
    operationType,
    pagination,
    queryForm,
    selectedRows
  ]);

  /** 删除 */
  const handleDelete = useCallback(() => {
    if (isEmpty(selectedRowKeys)) return;

    generateCommonDeleteModal({
      title: '是否确定删除这些字典项?',
      onOk() {
        setLoading(true);
        request({
          url: '/develop/dictionary/item',
          method: 'DELETE',
          data: selectedRowKeys
        })
          .then(async (res: any) => {
            if (res) {
              notification.success();
              const params = await getFormValues(queryForm);
              // 查询最新数据
              handleQueryData({ dictId: currentDictId, params });
            }
          })
          .finally(() => {
            setLoading(false);
          });
      }
    });
  }, [currentDictId, handleQueryData, queryForm, selectedRowKeys]);

  /** 查询条配置列表 */
  const queryFromItems = useMemo(
    () => [
      {
        name: 'option',
        label: '名称',
        children: <Input />
      },
      {
        name: 'value',
        label: '值',
        children: <InputNumber min={0} precision={0} style={COMPLETELY_FILL_STYLE} />
      }
    ],
    []
  );

  /** 编辑表单配置列表 */
  const editFormItems = useMemo(
    () => [
      {
        name: 'option',
        label: '名称',
        rules: [COMMON_REQUIRE_RULE],
        children: <Input />
      },
      {
        name: 'value',
        label: '值',
        rules: [COMMON_REQUIRE_RULE],
        children: <InputNumber min={0} precision={0} style={COMPLETELY_FILL_STYLE} />
      },
      {
        name: 'weight',
        label: '序号',
        rules: [COMMON_REQUIRE_RULE],
        children: <InputNumber min={0} precision={0} style={COMPLETELY_FILL_STYLE} />
      },
      {
        name: 'remark',
        label: '备注',
        children: <Input.TextArea />
      }
    ],
    []
  );

  /** 表格列配置 */
  const columns = useMemo(
    () => [
      {
        title: '名称',
        dataIndex: 'option'
      },
      {
        title: '值',
        dataIndex: 'value'
      }
    ],
    []
  );

  /** 勾选配置 */
  const rowSelection = {
    selectedRowKeys,
    onChange: (newSelectedRowKeys: React.Key[], newSelectedRows: any[]) => {
      setSelectedRowKeys(newSelectedRowKeys);
      setSelectedRows(newSelectedRows);
    }
  };

  return (
    <Spin spinning={loading}>
      <CollapseQueryBar
        form={queryForm}
        queryFromItems={queryFromItems}
        handleSearch={handleSearch}
        isIconBtn
        columns={2}
      />
      <div style={{ textAlign: 'right', marginBottom: 8 }}>
        <Badge.Ribbon placement="start" text={currentOption || '无可操作字典'}>
          <Space>
            <Button
              type="primary"
              disabled={!currentDictId}
              onClick={() => handleOpenEditDrawer('create')}
            >
              新增
            </Button>
            <Button
              type="primary"
              disabled={!currentDictId || selectedRows.length !== 1}
              onClick={() => handleOpenEditDrawer('update')}
            >
              修改
            </Button>
            <Button
              type="primary"
              danger
              disabled={!currentDictId || !selectedRowKeys.length}
              onClick={handleDelete}
            >
              删除
            </Button>
          </Space>
        </Badge.Ribbon>
      </div>
      <Table
        rowKey="id"
        columns={columns}
        dataSource={tableData}
        pagination={pagination}
        onChange={handleTableChange}
        rowSelection={rowSelection}
        sticky // 表头随页面滚动固定
      />
      {openFlag && (
        <EditDrawerForm
          title={operationType === 'update' ? '编辑' : '新增'}
          openFlag={openFlag}
          setOpenFlag={setOpenFlag}
          form={editForm}
          handleSave={handleSave}
          loading={saveLoading}
          formItems={editFormItems}
        />
      )}
    </Spin>
  );
};

export default DictionaryItems;
